package org.tema.ejb;

import java.sql.Date;
import java.util.Collection;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.tema.entities.Product;
import org.tema.entities.TestSpecification;
import org.tema.entities.User;




@Stateless
public class TestSpecBean implements TestSpecBeanLocal {

	@PersistenceContext
	private EntityManager entityManager;
	
	@EJB
	ProductBeanLocal productBean;
	
	@EJB
	UserBeanLocal userBean;
	

	
    public TestSpecBean() {
        // TODO Auto-generated constructor stub
    }
    
    
    public TestSpecification addTestSpec( String summary, String description, Date cDate, Date mDate, Product product, User currentUser ){
    	
    	TestSpecification testSpec = new TestSpecification();
    	User cUser = userBean.findUserByName(currentUser.getName());
    	testSpec.setSummary(summary);
    	testSpec.setDescription(description);
    	testSpec.setCreationDate(cDate);
    	testSpec.setModificationDate(mDate);	
    	testSpec.setCreator(cUser);
    	testSpec.setProduct(product);
		entityManager.persist(testSpec);
		return testSpec;
    }
    
	public TestSpecification  updateTestSpec(TestSpecification testSpecification, User modifier){
		User modifierUser = userBean.findUserByName(modifier.getName());
		testSpecification.setModifier(modifierUser);
		entityManager.merge(testSpecification);
	    return testSpecification;
	}
	
	public TestSpecification undoTestSpecChanges(TestSpecification testSpecification){
		entityManager.refresh(entityManager.merge(testSpecification));
	    return testSpecification;
	}
	
	public void deleteTestSpec(TestSpecification testSpecification){
		
		entityManager.remove(entityManager.merge(testSpecification));
		
	}

	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findAllTestSpecs(){
		Query query = entityManager.createQuery(" SELECT c FROM TestSpecification c ");
		return (Collection <TestSpecification>) query.getResultList();
	}
	
	//search methods
	public TestSpecification findTestSpecById( int id ){
		TestSpecification ts;
		Query query;
		try{
			query = entityManager.createQuery(" SELECT c FROM TestSpecification c WHERE c.id = :id  ");
			query.setParameter("id", id);
			ts =  ( TestSpecification ) query.getSingleResult();
		}
		catch (NoResultException e) {
			throw new IllegalArgumentException("no test specification  with id: '" + id + "'");
		}
		return ts;
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification > findTestSpecByProductId( int productId ){
		Product product = productBean.findProductById(productId);
		Set <TestSpecification> testSpecifications = product.getTestSpecificationSet();
		return (Collection <TestSpecification>) testSpecifications;
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification > findTestSpecByProductName( String productName ){
		Product product = productBean.findProductByName( productName );
		Set <TestSpecification> testSpecifications = product.getTestSpecificationSet();
		return (Collection <TestSpecification>) testSpecifications;
	}
	
	//may be multiple test specifications with likewise summaries
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findTestSpecsBySummary( String summary ){
		Collection <TestSpecification> ts;
		Query query;
		summary = summary.concat("%");
		query = entityManager.createQuery(" SELECT c FROM TestSpecification c WHERE c.summary LIKE :summary");
		query.setParameter("summary", summary);
		ts =  ( Collection <TestSpecification> ) query.getResultList();

		return ts;
	}
	
	@SuppressWarnings("unchecked")
	public TestSpecification findTestSpecBySummary( String summary ){
		TestSpecification ts;
		Query query;
		try{
			query = entityManager.createQuery(" SELECT c FROM TestSpecification c WHERE c.summary = :summary");
			query.setParameter("summary", summary);
			ts =  (TestSpecification ) query.getSingleResult();
		}
		catch (NoResultException e) {
			throw new IllegalArgumentException("no test specification  with id: '" + summary + "'");
		}
		return ts;
	}
	
	@SuppressWarnings("unchecked")
	public Collection  <TestSpecification> findTestSpecByCDate( Date cDate ){
		Query query = entityManager.createQuery(" SELECT c FROM TestSpecification c WHERE c.creationDate = :creationDate  ");
		query.setParameter("creationDate", cDate);
		return (Collection <TestSpecification>) query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findTestSpecByMDate( Date mDate ){
		Query query = entityManager.createQuery(" SELECT c FROM TestSpecification c WHERE c.creationDate = :creationDate  ");
		query.setParameter("modificationDate", mDate);
		return (Collection <TestSpecification>) query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findTestSpecByCreatorId( int cId ){
		User creator = userBean.findUserById(cId);
		return (Collection <TestSpecification>) creator.getSpecSetCreator();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findTestSpecByCreatorName( String cName ){
		User creator = userBean.findUserByName( cName );
		return (Collection <TestSpecification>) creator.getSpecSetCreator();
	}
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findTestSpecByModifierId( int cId ){
		User modifier = userBean.findUserById(cId);
		return (Collection <TestSpecification>) modifier.getSpecSetModifier();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestSpecification> findTestSpecByModifierName( String cName ){
		User modifier = userBean.findUserByName( cName );
		return (Collection <TestSpecification>) modifier.getSpecSetModifier();
	}
}
